﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using VideoLan;
using System.Threading;
using System.Runtime.InteropServices;

namespace MulticastTV
{
    /// <summary>
    /// New vlc instance in new form (PIP)
    /// </summary>
    public partial class VlcNewWindowForm : Form
    {
        VideoLan.VideoLanClient vlc_new;
        VideoLan.VlcMediaPlayer player_new;
        Form1 parent;
        public ChannelData cd;
        static bool mouseleft = false;
        string ar = "default";

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="_cd">Channel data</param>
        /// <param name="_parent">Main form</param>
        public VlcNewWindowForm(ChannelData _cd, Form1 _parent)
        {
            InitializeComponent();
            parent = _parent;
            cd = _cd;
            parent.pipInstances++;
            ar = parent.curar;
        }

        private void Form4_Load(object sender, EventArgs e)
        {
            // disable parent topmost if in full screen
            if (Properties.Settings.Default.FullScreen)
                parent.TopMost = false;
            
            if (parent.pipInstances <= 1)
            {
                if (Properties.Settings.Default.ShowInNewWindowLocation != new Point(0, 0))
                {
                    this.Location = Properties.Settings.Default.ShowInNewWindowLocation;
                }
            }
            else
            { 
                if (parent.pipInstances >1)
                {
                    int screenheight = Screen.PrimaryScreen.Bounds.Height;
                    int vpos = Properties.Settings.Default.ShowInNewWindowLocation.Y + (Properties.Settings.Default.ShowInNewWindowSize.Height * (parent.pipInstances-2));
                    if (vpos > screenheight - (Properties.Settings.Default.ShowInNewWindowSize.Height*2))
                        vpos = Math.Max(0,Properties.Settings.Default.ShowInNewWindowLocation.Y - (Properties.Settings.Default.ShowInNewWindowSize.Height * (parent.pipInstances - 2)));
                    else
                        vpos = Math.Min(screenheight-Properties.Settings.Default.ShowInNewWindowSize.Height,vpos+Properties.Settings.Default.ShowInNewWindowSize.Height);

                    this.Location = new Point(Properties.Settings.Default.ShowInNewWindowLocation.X, vpos);
                }
            }

            Properties.Settings.Default.WindowViewPIP = true;
            setWindowMode();

            if (Properties.Settings.Default.ShowInNewWindowSize != new Size(0,0))
                this.Size = Properties.Settings.Default.ShowInNewWindowSize;
            
            string path = AppDomain.CurrentDomain.BaseDirectory;

            // Vlc settings are the same as the main form vlc instance. AddOption method sets settings only for this instance.

            parent.pip_last_instance = null;
            parent.pip_last_instance = this;
            vlc_new = new VideoLan.VideoLanClient(path);
            player_new = vlc_new.NewMediaPlayer(this.Handle);
            player_new.StateChanged+=new EventHandler<StateChangedEventArgs>(player_new_StateChanged);

            VideoLan.VlcMedia media1 = vlc_new.NewMedia(System.Text.Encoding.UTF8.GetBytes("udp://@"+cd.Ip));
            //media1.AddOption(":plugin-path=" + path + @"\plugins\");
            media1.AddOption(System.Text.Encoding.UTF8.GetBytes(":croppadd-croptop=4"));
            media1.AddOption(System.Text.Encoding.UTF8.GetBytes(":croppadd-cropbottom=4"));
            media1.AddOption(System.Text.Encoding.UTF8.GetBytes(":croppadd-cropleft=4"));
            media1.AddOption(System.Text.Encoding.UTF8.GetBytes(":croppadd-cropright=4"));

            player_new.Load(media1);
            media1.Dispose();
            player_new.Play();
            player_new.Audio.Mute = true;
        }

        private void Form4_FormClosing(object sender, FormClosingEventArgs e)
        {
            IAsyncResult result = BeginInvoke(new delegateNoParams(stopAndClean));
            EndInvoke(result);

            if (parent.pipInstances <= 1)
            {
                Properties.Settings.Default.ShowInNewWindowLocation = this.Location;
                Properties.Settings.Default.ShowInNewWindowSize = this.Size;
                Properties.Settings.Default.Save();
            }
        }

       public delegate void delegateNoParams();
        
       private void stopAndClean()
       {
            // Dirty, but prevents deadlock.
            player_new = null;
            vlc_new = null;
            GC.Collect();
        }

        private void setWindowMode()
        {
            if (Properties.Settings.Default.WindowViewPIP)
            {
                this.Text = "";
                this.ControlBox = false;
                this.WindowState = FormWindowState.Normal;
                this.FormBorderStyle = FormBorderStyle.Sizable;
            }
            else
            {
                this.ControlBox = true;
                this.Text = "MulticastTV";
                this.WindowState = FormWindowState.Normal;
            }
        }

        private void Form4_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Properties.Settings.Default.KeyMute)
                player_new.Audio.ToggleMute();
            if (e.KeyData == Properties.Settings.Default.KeyMinimal)
            {
                if (Properties.Settings.Default.WindowViewPIP)
                    Properties.Settings.Default.WindowViewPIP = false;
                else
                    Properties.Settings.Default.WindowViewPIP = true;
                setWindowMode();
            }
            if (e.KeyData== Properties.Settings.Default.KeyQuit)
                exit();
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            exit();
        }

        private void minimalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.WindowViewPIP)
                Properties.Settings.Default.WindowViewPIP = false;
            else
                Properties.Settings.Default.WindowViewPIP = true;
            setWindowMode();
        }

        //Should we change volume in main window too ?
        private void muteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (player_new != null && player_new.State != VlcState.Ended && player_new.State != VlcState.Stopped)
            {
                if (player_new.Audio.Mute)
                    player_new.Audio.Mute = false;
                else
                    player_new.Audio.Mute = true;
            }
        }

        public void exit()
        {
            this.Close();
        }
       
        private void VlcNewWindowForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            parent.pipInstances--;
        }

        /// <summary>
        /// Vlc events
        /// </summary>
        private void player_new_StateChanged(object sender, StateChangedEventArgs e)
        {
            switch (e.NewState)
            {
                case VlcState.Ended:
                    
                    break;
                case VlcState.Error:
                    //Handle playing error
                    break;
                case VlcState.Buffering:

                    break;
                case VlcState.Playing:
                    // update max
                    break;

            }
        }
        private Point distanceFormMouse;
        private void VlcNewWindowForm_MouseUp(object sender, MouseEventArgs e)
        {
            mouseleft = false;
        }

        private void VlcNewWindowForm_MouseDown(object sender, MouseEventArgs e)
        {
            distanceFormMouse = new Point(MousePosition.X - this.Location.X, MousePosition.Y - this.Location.Y);
            mouseleft = true;
        }

        private void VlcNewWindowForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseleft)
                this.Location = new Point(MousePosition.X - distanceFormMouse.X, MousePosition.Y - distanceFormMouse.Y);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        protected override void WndProc(ref Message m)
        {
            //remote controll
            if (m.Msg == 0x8888 && Properties.Settings.Default.RemoteMode2) // TODO: remote mode should be checked in constructor!
            {
                //repost to parent
                PostMessage(parent.Handle, m.Msg, (int)m.WParam, (int)m.LParam);
                m.Result = new IntPtr(0);
            }
            else
            {
                base.WndProc(ref m);
            }
        }
    }
}
